using B.S.Database.Domain.Entity;
using B.S.Database.ErrorCode;
using B.S.Database.Interface.Interface;
using B.S.Database.Write.Api.Application.Commands.Image;
using B.S.Database.Write.Api.SysConfig;
using MediatR;
using Microsoft.Extensions.Options;
using Qiniu.Http;
using Qiniu.Storage;
using Qiniu.Util;
using System.Reflection;

namespace B.S.Database.Write.Api.Application.CommandHandler.Image
{
    public class PictureUploadAndCreateCommandHandler : IRequestHandler<PictureUploadAndCreateCommands, Apiresult<object>>
    {
        private readonly IBaseResotity<Picture_Information> _pictureRepository;
        private readonly IOptions<QiNiuConfig> _qiniuConfig;
        private readonly ILogger<PictureUploadAndCreateCommandHandler> _logger;

        public PictureUploadAndCreateCommandHandler(
            IBaseResotity<Picture_Information> pictureRepository, 
            IOptions<QiNiuConfig> qiniuConfig,
            ILogger<PictureUploadAndCreateCommandHandler> logger)
        {
            _pictureRepository = pictureRepository;
            _qiniuConfig = qiniuConfig;
            _logger = logger;
        }

        public async Task<Apiresult<object>> Handle(PictureUploadAndCreateCommands request, CancellationToken cancellationToken)
        {
            var result = new Apiresult<object>();

            try
            {
                // 验证请求
                if (request.TraceabilityId <= 0)
                {
                    result.Code = ApiEnums.失败;
                    result.Message = "溯源ID不能为空";
                    return result;
                }

                if (request.File == null && (request.Files == null || !request.Files.Any()))
                {
                    result.Code = ApiEnums.失败;
                    result.Message = "请选择要上传的图片文件";
                    return result;
                }

                // 验证图片类型
                if (!IsValidImageType(request.ImageType))
                {
                    result.Code = ApiEnums.失败;
                    result.Message = "无效的图片类型";
                    return result;
                }

                // 上传图片到七牛云
                var uploadedUrls = new List<string>();

                // 处理单个文件
                if (request.File != null)
                {
                    var uploadResult = await UploadToQiniu(request.File);
                    if (uploadResult.Success)
                    {
                        uploadedUrls.Add(uploadResult.Url);
                    }
                    else
                    {
                        result.Code = ApiEnums.失败;
                        result.Message = uploadResult.Message;
                        return result;
                    }
                }

                // 处理多个文件
                if (request.Files != null && request.Files.Any())
                {
                    foreach (var file in request.Files)
                    {
                        var uploadResult = await UploadToQiniu(file);
                        if (uploadResult.Success)
                        {
                            uploadedUrls.Add(uploadResult.Url);
                        }
                        else
                        {
                            _logger.LogWarning($"文件 {file.FileName} 上传失败: {uploadResult.Message}");
                        }
                    }
                }

                if (!uploadedUrls.Any())
                {
                    result.Code = ApiEnums.失败;
                    result.Message = "没有文件成功上传";
                    return result;
                }

                // 保存到数据库
                await SaveToDatabase(request, uploadedUrls);

                result.Code = ApiEnums.成功;
                result.Message = "图片上传并保存成功";
                result.Data = new
                {
                    UploadedUrls = uploadedUrls,
                    TraceabilityId = request.TraceabilityId,
                    ImageType = request.ImageType
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "图片上传和保存过程中发生错误");
                result.Code = ApiEnums.失败;
                result.Message = $"图片上传和保存失败: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// 上传文件到七牛云
        /// </summary>
        private async Task<(bool Success, string Url, string Message)> UploadToQiniu(IFormFile file)
        {
            try
            {
                // 验证文件类型
                if (!IsImageFile(file))
                {
                    return (false, "", "只允许上传图片文件");
                }

                // 获取七牛云配置
                var config = _qiniuConfig.Value;
                if (string.IsNullOrEmpty(config.AccessKey) || string.IsNullOrEmpty(config.SecretKey) || string.IsNullOrEmpty(config.Bucket))
                {
                    return (false, "", "七牛云配置不完整");
                }

                // 生成文件名和路径
                string fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
                string fileName = $"{Guid.NewGuid():N}{fileExtension}";
                string dateFolder = DateTime.Now.ToString("yyyy/MM/dd");
                string saveKey = $"Pic/{dateFolder}/{fileName}";

                // 七牛云上传逻辑
                var mac = new Mac(config.AccessKey, config.SecretKey);
                var putPolicy = new PutPolicy { Scope = config.Bucket };
                putPolicy.SetExpires(3600);
                string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
                var qnConfig = new Config { Zone = Zone.ZONE_CN_North };
                var formUploader = new FormUploader(qnConfig);

                using (var ms = new MemoryStream())
                {
                    await file.CopyToAsync(ms);
                    var result = formUploader.UploadData(ms.ToArray(), saveKey, token, null);

                    if (result.Code == 200)
                    {
                        string fileUrl = $"{config.BaseUrl.TrimEnd('/')}/{saveKey}";
                        _logger.LogInformation($"七牛云上传成功: {fileUrl}");
                        return (true, fileUrl, "上传成功");
                    }
                    else
                    {
                        _logger.LogError($"七牛云上传失败: Code={result.Code}, Text={result.Text}");
                        return (false, "", $"七牛云上传失败: {result.Text}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "七牛云上传异常");
                return (false, "", $"上传异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 保存图片URL到数据库
        /// </summary>
        private async Task SaveToDatabase(PictureUploadAndCreateCommands request, List<string> uploadedUrls)
        {
            // 检查是否已存在相同 TraceabilityId 的记录
            var existingPicture = _pictureRepository.GetAll().FirstOrDefault(x => x.TraceabilityId == request.TraceabilityId);

            if (existingPicture != null)
            {
                // 如果存在，根据追加模式处理
                var newImageUrls = string.Join(request.Separator, uploadedUrls);
                var propertyName = request.ImageType;

                if (request.IsAppend)
                {
                    // 追加模式：将新内容追加到现有内容后面
                    var existingValue = GetPropertyValue(existingPicture, propertyName);
                    var newValue = string.IsNullOrEmpty(existingValue) ? newImageUrls : $"{existingValue}{request.Separator}{newImageUrls}";
                    SetPropertyValue(existingPicture, propertyName, newValue);
                    _pictureRepository.Update(existingPicture);
                }
                else
                {
                    // 覆盖模式：直接替换现有内容
                    SetPropertyValue(existingPicture, propertyName, newImageUrls);
                    _pictureRepository.Update(existingPicture);
                }
            }
            else
            {
                // 如果不存在，则添加新记录
                var newPicture = new Picture_Information
                {
                    TraceabilityId = request.TraceabilityId
                };

                var newImageUrls = string.Join(request.Separator, uploadedUrls);
                SetPropertyValue(newPicture, request.ImageType, newImageUrls);

                _pictureRepository.Add(newPicture);
            }
        }

        /// <summary>
        /// 验证图片类型是否有效
        /// </summary>
        private bool IsValidImageType(string imageType)
        {
            var validTypes = new[]
            {
                "Inspection_Repor",
                "Livestock_Certification", 
                "Certification_Documents",
                "Food_Safety",
                "Raw_Material",
                "Auxiliary_Materials",
                "Additive_Materials",
                "Packaging_Materials",
                "Enterprise_Image"
            };

            return validTypes.Contains(imageType);
        }

        /// <summary>
        /// 验证是否为图片文件
        /// </summary>
        private bool IsImageFile(IFormFile file)
        {
            if (file == null) return false;

            string contentType = file.ContentType?.ToLower() ?? "";
            string extension = Path.GetExtension(file.FileName)?.ToLower() ?? "";

            var imageContentTypes = new[] { "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp", "image/webp" };
            var imageExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp" };

            return imageContentTypes.Contains(contentType) || imageExtensions.Contains(extension);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        private string GetPropertyValue(Picture_Information picture, string propertyName)
        {
            var property = typeof(Picture_Information).GetProperty(propertyName);
            return property?.GetValue(picture)?.ToString() ?? "";
        }

        /// <summary>
        /// 设置属性值
        /// </summary>
        private void SetPropertyValue(Picture_Information picture, string propertyName, string value)
        {
            var property = typeof(Picture_Information).GetProperty(propertyName);
            property?.SetValue(picture, value);
        }
    }
} 